Source
from typing import Generic, TypeVar
_T = TypeVar("_T")
class MyGenericClass(Generic[_T]):
def __init__(self) -> None:
TType: type[_T] = type(self).__orig_bases__[0].__args__[0]
t = TType(...)
# the naive approach of just using _T does not work, because it's just a typing annotation
t = _T(...) # raises `TypeError: 'TypeVar' object is not callable`
- as an alternative we can use
get_original_bases()
from thetyping
module (only available from Python 3.12; usetyping_extensions
for earlier versions instead) in combination withget_args()
for a more idiomatic version
from typing import get_args, get_original_bases
# ...
TType: type[_T] = get_args(get_original_bases(type(self)))
- note that this might not work in all cases because
get_original_bases()
usescls.__dict__.get("__orig_bases__", cls.__bases__)
internally, which is not functionally equivalent (at least in Python 3.10) - this can be mitigated by a custom implementation of
get_original_bases()
from typing import Iterable
def get_original_bases(cls: type, /) -> Iterable[type]:
"""
Return the class's "original" bases, similar to `typing.get_original_bases()` for Python 3.12+, but not using
`__orig_bases__` from the class's `__dict__` since this seems to not always be available that way
(`cls.__orig_bases__` is, though).
Parameters
----------
cls : type
The class to get the original bases for
Returns
-------
Iterable[type]
The original bases of the class
"""
return getattr(cls, "__orig_bases__", cls.__bases__)